package java学习.leetcode.editor.cn.数组;

/**
 * @author 刘世锦
 * 2022-09-28 10:08:09	 当前时间
 */
//给你一个正整数 n ，生成一个包含 1 到 n2 所有元素，且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 
//
// 
//
// 示例 1： 
//
// 
//输入：n = 3

//输出：  0 1 2
//  0  [[1,2,3],
// 	1   [8,9,4],
// 	2   [7,6,5]]
//      20 21 22
//
// 示例 2： 
//
// 
//输入：n = 1
//输出：[[1]]
// 
//
// 
//
// 提示： 
//
// 
// 1 <= n <= 20 
// 
// Related Topics 数组 矩阵 模拟 
// 👍 829 👎 0

public class 螺旋矩阵II{
	public static void main(String[] args) {
		Solution solution = new 螺旋矩阵II().new Solution();
		solution.generateMatrix(5);
	}

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int[][] generateMatrix(int n) {
		int[][] arr = new int[n][n];
		int num = 1;
//		定义上下左右四部分
		int left = 0,right=n-1;
		int  top = 0 ,bottom = n-1;
		while (num<=n*n){
//			横向遍历顶部第一层 从左到右
			for (int i = left; i <=right ; i++) {
				arr[top][i] = num++;
			}
//			top向下缩小
			top++;
//			纵向遍历右侧外层 从上到下
			for (int i =top ; i <=bottom ; i++) {
				arr[i][right] = num++;
			}
//  		右侧向左缩小
			right--;
//			遍历底部 从右到左
			for (int i = right; i >=left ; i--) {
				arr[bottom][i] = num++;
			}
//			底部向上缩小
			bottom--;
//			纵向遍历左侧 从下到上
			for (int i = bottom;i>=top;i--){
				arr[i][left] =num++;
			}
//			左侧向右缩小
			left++;
		}
		
		for (int i = 0; i <n ; i++) {
			for (int j = 0; j <n ; j++) {
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
		return arr;
	}

	public int[][] generateMatrix1(int n) {
		int l = 0, r = n - 1, t = 0, b = n - 1;
		int[][] mat = new int[n][n];
		int num = 1, tar = n * n;
		while(num <= tar){
			for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
			t++;
			for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
			r--;
			for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
			b--;
			for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
			l++;
		}
		return mat;
	}
	public int[][] generateMatrix2(int n) {
		int loop = 0;  // 控制循环次数
		int[][] res = new int[n][n];
		int start = 0;  // 每次循环的开始点(start, start)
		int count = 1;  // 定义填充数字
		int i, j;

		while (loop++ < n / 2) { // 判断边界后，loop从1开始
			// 模拟上侧从左到右
			for (j = start; j < n - loop; j++) {
				res[start][j] = count++;
			}

			// 模拟右侧从上到下
			for (i = start; i < n - loop; i++) {
				res[i][j] = count++;
			}

			// 模拟下侧从右到左
			for (; j >= loop; j--) {
				res[i][j] = count++;
			}

			// 模拟左侧从下到上
			for (; i >= loop; i--) {
				res[i][j] = count++;
			}
			start++;
		}

		if (n % 2 == 1) {
			res[start][start] = count;
		}

		return res;
	}
}
//leetcode submit region end(Prohibit modification and deletion)

}
